#include "bsp.h"

#include "SW_I2C/sw_i2c.h"	
#include "SW_I2C/sw_i2c_ex.h"


/* 定义IO = 1和 0的代码  */
#define I2C_SDA_1()		AT24CXX_SDA_PORT->BSRR = AT24CXX_SDA_PIN
#define I2C_SDA_0()		AT24CXX_SDA_PORT->BSRR = AT24CXX_SDA_PIN << 16;

#define I2C_SCL_1()		AT24CXX_SCL_PORT->BSRR = AT24CXX_SCL_PIN
#define I2C_SCL_0()		AT24CXX_SCL_PORT->BSRR = AT24CXX_SCL_PIN << 16;

#define I2C_SDA_READ()  ((AT24CXX_SDA_PORT->IDR & AT24CXX_SDA_PIN) != 0)	/* 读SDA口线状态 */
#define I2C_SCL_READ()  ((AT24CXX_SCL_PORT->IDR & AT24CXX_SCL_PIN) != 0)	/* 读SCL口线状态 */

#define I2C_WR	0		/* 写控制bit */
#define I2C_RD	1		/* 读控制bit */

// I2C总线时序接口函数
static void I2C_SDA_LOW(void);
static void I2C_SDA_HIGH(void);
static void I2C_SCL_LOW(void);
static void I2C_SCL_HIGH(void);
static uint8_t I2C_SDA_READ_LEVEL(void);
static void I2C_SDA_SET_INPUT(void);
static void I2C_SDA_SET_OUTPUT(void);
static void I2C_Delay(uint32_t us);


/* Private variables ---------------------------------------------------------*/
// 定义i2c驱动对象
static sw_i2c_dev_t i2c_at24cxx_dev;


void ee_write_cycle_delay(void) {
    HAL_Delay_ms(5);  // AT24C02 典型写周期为 5ms
}


void at24cxx_gpio_config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 打开GPIO时钟 */
    RCC_AHB1PeriphClockCmd(RCC_AT24CXX_PORT, ENABLE);

    /* 配置为开漏输出 */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;		/* 设为输出口 */
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_InitStructure.GPIO_Pin = AT24CXX_SDA_PIN;
    GPIO_Init(AT24CXX_SDA_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = AT24CXX_SCL_PIN;
    GPIO_Init(AT24CXX_SCL_PORT, &GPIO_InitStructure);

    /*释放SCL和SDA*/
    I2C_SDA_1();
    I2C_SCL_1();

}

void at24cxx_i2c_config(void)
{
    i2c_at24cxx_dev.name               = "i2c_at24cxx";
    i2c_at24cxx_dev.speed              = 2; /*! speed:105Hz */
    i2c_at24cxx_dev.delay_us           = I2C_Delay;
    i2c_at24cxx_dev.ops.sda_low        = I2C_SDA_LOW;
    i2c_at24cxx_dev.ops.sda_high       = I2C_SDA_HIGH;
    i2c_at24cxx_dev.ops.scl_low        = I2C_SCL_LOW;
    i2c_at24cxx_dev.ops.scl_high       = I2C_SCL_HIGH;
    i2c_at24cxx_dev.ops.sda_read_level = I2C_SDA_READ_LEVEL;
    i2c_at24cxx_dev.ops.sda_set_input  = I2C_SDA_SET_INPUT;
    i2c_at24cxx_dev.ops.sda_set_output = I2C_SDA_SET_OUTPUT;
    sw_i2c_init(&i2c_at24cxx_dev); 
}


void bsp_at24cxx_init(void)
{
    // 引脚初始化
    at24cxx_gpio_config();
    // 软件i2c初始化
    at24cxx_i2c_config();
}


// 函数：bsp_at24cxx_write_byte
// 功能：向AT24CXX芯片写入一个字节
// 参数：addr：要写入的地址；data：要写入的数据
// 返回值：无
uint8_t bsp_at24cxx_write_byte(uint32_t addr, uint8_t data)
{
    uint8_t ret = 0;
    // 调用sw_i2c_ex_write_byte函数，向AT24CXX芯片写入一个字节
    ret = sw_i2c_ex_write_byte(&i2c_at24cxx_dev, AT24CXX_I2C_ADDR, addr, data);
    if(ret != 0) {
        return ret;
    }
    // 延时一段时间，等待写入完成
    ee_write_cycle_delay();  
    return ret;
}

// 函数：bsp_at24cxx_read_byte
// 功能：从AT24CXX芯片中读取一个字节的数据
// 参数：addr：要读取的地址；data：存储读取数据的指针
uint8_t bsp_at24cxx_read_byte(uint32_t addr, uint8_t *data)
{
    // 调用sw_i2c_ex_read_byte函数，从AT24CXX芯片中读取一个字节的数据
    return sw_i2c_ex_read_byte(&i2c_at24cxx_dev, AT24CXX_I2C_ADDR, addr, data);
}

uint8_t bsp_at24cxx_write_bytes(uint32_t addr, uint8_t *data, uint16_t len)
{
    uint8_t data_buf[EE_ADDR_BYTES + EE_PAGE_SIZE];
    sw_i2c_msg_t sw_i2c_msg; 

    if(len == 0 || (addr+len) > EE_SIZE) {
        return 1;
    }
    sw_i2c_msg.buf = data_buf;
    while(len > 0) {
        // 计算当前页剩余空间
        uint8_t page_offset = addr % EE_PAGE_SIZE;
        uint8_t bytes_to_write = EE_PAGE_SIZE - page_offset;

        // 限制本次写入长度
        if (bytes_to_write > len) {
            bytes_to_write = len;
        }

        sw_i2c_msg.addr = AT24CXX_I2C_ADDR;
        sw_i2c_msg.flags = SW_I2C_FLAG_WR;
        sw_i2c_msg.buf[0] = addr; // 启始地址
        memcpy(sw_i2c_msg.buf+1, data, bytes_to_write);
        sw_i2c_msg.len = bytes_to_write + 1;
        if(I2C_SUCCESS != sw_i2c_transfer(&i2c_at24cxx_dev, &sw_i2c_msg, 1))
        {
            return 2;
        }

        // 更新指针和剩余长度
        addr += bytes_to_write;
        data += bytes_to_write;
        len -= bytes_to_write;
        // 等待写入完成
        ee_write_cycle_delay();
    }
    return 0;

}

uint8_t bsp_at24cxx_read_bytes(uint32_t addr, uint8_t *data, uint16_t len)
{
    if(len == 0 || (addr+len) > EE_SIZE) {
        return 1;
    }
    return sw_i2c_ex_read_bytes(&i2c_at24cxx_dev, AT24CXX_I2C_ADDR, addr, data, len);
}

uint8_t bsp_at24cxx_test(void)
{
    uint16_t i;
    uint8_t write_data_array[256] = {0};
    uint8_t read_data_array[256] = {0};
    for(i = 0; i < 256; i++)
    {
        if(i%2)
        {
            write_data_array[i] = 0x55;
        }
        else
        {
            write_data_array[i] = 0xAA;
        }
    }
    bsp_at24cxx_write_bytes(0x00, write_data_array, sizeof(write_data_array));
    bsp_at24cxx_read_bytes(0x00, read_data_array, sizeof(read_data_array));
    for (i = 0; i < 256; i++)
    {
        if(write_data_array[i] != read_data_array[i])
        {
            return 1;
        }
    }
    return 0;
    
}

uint8_t bsp_at24cxx_check(void)
{
    uint8_t data_buf[1];
    sw_i2c_msg_t sw_i2c_msg; 
    sw_i2c_msg.buf = data_buf;
    sw_i2c_msg.addr = AT24CXX_I2C_ADDR;
    sw_i2c_msg.flags = SW_I2C_FLAG_WR;
    sw_i2c_msg.len = 1;
    return sw_i2c_transfer(&i2c_at24cxx_dev, &sw_i2c_msg, 1);
}

/***********************************************************************/


static void I2C_SDA_LOW(void)
{
    I2C_SDA_0();
}

static void I2C_SDA_HIGH(void)
{
    I2C_SDA_1();
}

static void I2C_SCL_LOW(void)
{
    I2C_SCL_0();
}

static void I2C_SCL_HIGH(void)
{
    I2C_SCL_1();
}

static uint8_t I2C_SDA_READ_LEVEL(void)
{
    return I2C_SDA_READ();
}

static void I2C_SDA_SET_INPUT(void)
{
    I2C_SDA_1(); // 释放SDA引脚

}

static void I2C_SDA_SET_OUTPUT(void)
{

}

static void I2C_Delay(uint32_t us)
{
    HAL_Delay_us(us);
}



